home *** CD-ROM | disk | FTP | other *** search
/ Aminet 8 / Aminet 8 (1995)(GTI - Schatztruhe)[!][Oct 1995].iso / Aminet / comm / tcp / socklink100.lha / socklink / socklink.c < prev    next >
C/C++ Source or Header  |  1995-09-01  |  12KB  |  347 lines

  1. /*****************************************************************************\
  2. *                                                                             *
  3. * socklink.c -- links a socket to stdio                                       *
  4. *                                                                             *
  5. * Copyright (c) 1995 by Sam Yee.                                              *
  6. * Source freely redistributable in unmodified form.                           *
  7. *                                                                             *
  8. * $ Author:       Sam Yee (samy@sfu.ca) $                                     *
  9. * $ Project:      socklink $                                                  *
  10. * $ Date Started: May 17, 1995 $                                              *
  11. * $ Version:      1.00 (1.9.95) $                                             *
  12. *                                                                             *
  13. * History:                                                                    *
  14. * Ver. YY/MM/DD Who                Modifications                              *
  15. * --------------------------------------------------------------------------- *
  16. * 1.00 95/09/01 Sam Yee            Original release                           *
  17. *                                                                             *
  18. \*****************************************************************************/
  19.  
  20. #include <clib/dos_protos.h>
  21. #include <clib/exec_protos.h>
  22. #include <devices/timer.h>
  23. #include <dos/dos.h>
  24. #include <exec/types.h>
  25. #include <exec/libraries.h>
  26. #include <exec/execbase.h>
  27. #include <pragmas/dos_pragmas.h>
  28. #include <pragmas/exec_pragmas.h>
  29. #include <errno.h>
  30. #include <stdlib.h>
  31.  
  32. #ifdef _AMITCP
  33. #include <bsdsocket.h>
  34. #include <netinet/in.h>
  35. #include <netdb.h>
  36. #include <sys/ioctl.h>
  37. #include <sys/time.h>
  38. #include <sys/types.h>
  39. #include <syslog.h>
  40. #include <amitcp/socketbasetags.h>
  41. #include <string.h>
  42.  
  43. #else
  44.  
  45. #include <proto/all.h>
  46. #include <sys/types.h>
  47. #include <sys/socket.h>
  48. #include <signal.h>
  49.  
  50. #include <netdb.h>
  51. #include <sys/ioctl.h>
  52. #include <ss/socket.h>
  53.  
  54. #define WaitSelect selectwait
  55. #define CloseSocket s_close
  56. #define IoctlSocket s_ioctl
  57.  
  58. #endif /* _AMITCP */
  59.  
  60. #ifndef TRUE
  61. #define TRUE    1
  62. #define FALSE   0
  63. #endif /* TRUE */
  64.  
  65. #define VERSION "1.00"
  66.  
  67. #ifndef BOOL
  68. #define short BOOL
  69. #endif /* BOOL */
  70.  
  71. #define RAWIN_RUNTIME
  72. #include "RawIN.h"
  73.  
  74. /*****************************************************************************/
  75. const char version[] = "\0$VER: SockLink/"
  76. #ifdef _AMITCP
  77. "AmiTCP"
  78. #else
  79. "AS225r2"
  80. #endif /* _AMITCP */
  81.                        " "VERSION" (1.9.95)";
  82.  
  83. extern struct DosLibrary    *DOSBase;
  84.  
  85. #ifdef _AMITCP
  86. extern STRPTR   _ProgramName;   /* provided by SAS/C startup */
  87. struct Library  *SocketBase;
  88. int             h_errno = 0;
  89. #else
  90. struct Library  *SockBase;
  91. #endif /* !_AMITCP */
  92.  
  93. /*****************************************************************************/
  94. /* prototypes */
  95. void __regargs __chkabort(void);    /* disable SAS/C ^C checking */
  96. void __regargs __chkabort(){}
  97. void __regargs _CXBRK(void);
  98. void __regargs _CXBRK(){}
  99.  
  100. int connect_server(char *prog_name, char *host_name, int port);
  101. int init_socklib(void);
  102. void cleanup_socklib(void);
  103.  
  104. /*****************************************************************************/
  105. int
  106. main(int  argc,
  107.      char *argv[])
  108. {
  109.     struct Library  *RawINBase;
  110.     struct Line     *line;
  111.     BOOL            sock_writing = FALSE;
  112.     char            *prog_name,
  113.                     sockout_buf[256],
  114.                     stdout_buf[256];
  115.     int             sock,
  116.                     select_return,
  117.                     read_len,
  118.                     break_count = 0,
  119.                     wait_seconds = 0,
  120.                     rc = 10;
  121.     fd_set          r_fds,
  122.                     w_fds,
  123.                     readmask,
  124.                     writemask;
  125.     u_long          wait_mask,
  126.                     return_mask;
  127.  
  128.     prog_name = FilePart(argv[0]);
  129.  
  130.     if (argc < 3)
  131.         Printf("Usage: %s <host> <port> [start-delay-seconds]\n",prog_name);
  132.     else
  133.     {
  134.         if (!init_socklib())
  135.         {
  136.             if ((sock = connect_server(prog_name,argv[1],atoi(argv[2]))) >= 0)
  137.             {
  138.                 if (RawINBase = OpenLibrary(RAWIN_NAME,0))
  139.                 {
  140.                     if (line = RI_AllocLine(2L,2L))
  141.                     {
  142.                         rc = 0;
  143.                         Printf("SockLink " VERSION " (" __DATE__ " " __TIME__ ") -- links stdio to socket\n"
  144.                                "Copyright (c) by Sam Yee (samy@sfu.ca).  Freely distributable.\n"
  145.                                "Press ^C^C^C (3 Control-C's) to terminate.\n\n"
  146.                                "Connected to %s at port %ld.\n"
  147.                                ,argv[1],atoi(argv[2]));
  148.  
  149.                         if (argc > 3)
  150.                         {
  151.                             struct timeval tv;
  152.  
  153.                             wait_seconds = atol(argv[3]);
  154.                             Printf("Linking stdio to socket in %ld seconds.\n\n",wait_seconds);
  155. #ifdef _AMITCP
  156.                             tv.tv_sec = wait_seconds;
  157.                             tv.tv_usec = 0;
  158. #else
  159.                             tv.tv_secs = wait_seconds;
  160.                             tv.tv_micro = 0;
  161. #endif /* _AMITCP */
  162.                             select(0,NULL,NULL,NULL,&tv);
  163.                         }
  164.                         else
  165.                             Printf("\n");
  166.  
  167.                         wait_mask = SIGBREAKF_CTRL_C |
  168.                                     (1L << line->ReadReplyPort->mp_SigBit);
  169.                         RI_SendReadRequest(line);   /* send a request to the input handler */
  170.                         FD_SET(sock,&r_fds);
  171.                         FD_SET(sock,&w_fds);
  172.  
  173.                         /* keeping going until something goes bad */
  174.                         while (!(line->flags & (LNF_EOF|LNF_BREAKC|LNF_READERROR|LNF_WRITEERROR)))
  175.                         {
  176.                             return_mask = wait_mask;
  177.                             readmask = r_fds;
  178.                             writemask = w_fds;
  179.  
  180.                             select_return = WaitSelect(sock+1,&readmask,
  181.                                                        sock_writing ? &writemask : NULL,
  182.                                                        NULL,NULL,&return_mask);
  183.  
  184.                             if ((select_return < 0) && (errno != EINTR))
  185.                             {
  186.                                 Printf("\n\n%s: select returns %ld; errno=%ld\n",
  187.                                        prog_name,select_return,errno);
  188.                                 break;
  189.                             }
  190.  
  191.                             if (FD_ISSET(sock,&readmask))
  192.                             {
  193.                                 /* wait for a write to finish if needed */
  194.                                 RI_WaitWrite(line);
  195.  
  196.                                 if ((read_len = recv(sock,stdout_buf,sizeof(stdout_buf),0)) > 0)
  197.                                     RI_SendWriteRequest(line,stdout_buf,read_len);
  198.                                 else
  199.                                 {
  200.                                     Printf("\n\nEOF Connection closed by foreign host.\n");
  201.                                     break;
  202.                                 }
  203.                             }
  204.  
  205.                             if (sock_writing)
  206.                             {
  207.                                 if (FD_ISSET(sock,&writemask))
  208.                                     sock_writing = FALSE;
  209.                             }
  210.  
  211.                             /* we can't read from stdin if we are already writing to socket */
  212.                             if (!sock_writing)
  213.                             {
  214.                                 if ((read_len = RI_GetBlock(line,FALSE,FALSE,sockout_buf,
  215.                                                             sizeof(sockout_buf))) > 0L)
  216.                                 {
  217.                                     if (sockout_buf[0] == 0x03) /* ^C? */
  218.                                         break_count++;
  219.                                     else
  220.                                         break_count = 0;
  221.  
  222.                                     send(sock,sockout_buf,read_len,0);
  223.                                     sock_writing = TRUE;
  224.  
  225.                                     if (break_count != 3)
  226.                                         RI_SendReadRequest(line);
  227.                                     else
  228.                                         break;  /* ^C^C^C quits */
  229.                                 }
  230.                             }
  231.  
  232.                             if (return_mask & SIGBREAKF_CTRL_C)
  233.                                 break;
  234.                         }
  235.  
  236.                         RI_FreeLine(line);
  237.                     }
  238.  
  239.                     CloseLibrary(RawINBase);
  240.                 }
  241.  
  242.                 CloseSocket(sock);
  243.             }
  244.  
  245.             cleanup_socklib();
  246.         }
  247.         else
  248.             Printf("%s: TCP/IP stack not running\n",prog_name);
  249.     }
  250.  
  251.     return(rc);
  252. }
  253.  
  254. /*****************************************************************************/
  255. /* connects to a host at a specifc port */
  256. int /* socket descriptor if connection succeeded, else -1 */
  257. connect_server(char *prog_name,
  258.                char *host_name,
  259.                int  port)
  260. {
  261.     struct in_addr      defaddr;
  262.     struct hostent      *hp;
  263.     struct sockaddr_in  sin;
  264.     int                 sock;
  265.     long                onoff = 1;
  266.  
  267.     /* lookup the IP address of a host */
  268.     if (hp = gethostbyname(host_name))
  269.     {
  270.         sin.sin_family = hp->h_addrtype;
  271.         memcpy(&sin.sin_addr,hp->h_addr,hp->h_length);
  272.     }
  273.     else
  274.     {
  275.         if ((defaddr.s_addr = inet_addr(host_name)) == -1)
  276.         {
  277.             Printf("%s: unknown host: %s\n",prog_name,host_name);
  278.             return(-1);
  279.         }
  280.  
  281.         sin.sin_family = PF_INET;
  282.         memcpy(&sin.sin_addr,&defaddr,sizeof(struct in_addr));
  283.     }
  284.  
  285.     sin.sin_port = htons(port);
  286.  
  287.     /* open a socket */
  288.     if ((sock = socket(AF_INET,SOCK_STREAM,0)) >= 0)
  289.     {
  290.         /* connect sock to host */
  291.         if (connect(sock,(struct sockaddr *)&sin,sizeof(sin)) == -1)
  292.         {
  293.             Printf("%s: connection refused: errno=%ld\n",prog_name,errno);
  294.             CloseSocket(sock);
  295.             sock = -1;
  296.         }
  297.         else
  298.             IoctlSocket(sock,FIOASYNC,(caddr_t)&onoff);
  299.     }
  300.  
  301.     return(sock);
  302. }
  303.  
  304. /*****************************************************************************/
  305. /* opens socket library, or non-zero for error */
  306. int
  307. init_socklib(void)
  308. {
  309. #ifdef _AMITCP
  310.     if (SocketBase = OpenLibrary("bsdsocket.library",0L))
  311.     {
  312.         if (!SocketBaseTags(SBTM_SETVAL(SBTC_ERRNOPTR(sizeof(errno))), &errno,
  313.                             SBTM_SETVAL(SBTC_HERRNOLONGPTR), &h_errno,
  314.                             SBTM_SETVAL(SBTC_LOGTAGPTR), _ProgramName,
  315.                             TAG_END))
  316.             return(0);
  317.  
  318.         CloseLibrary(SocketBase);
  319.     }
  320.  
  321. #else
  322.  
  323.     if (SockBase = OpenLibrary("socket.library",0L))
  324.     {
  325.         setup_sockets(10,&errno);
  326.         return(0);
  327.     }
  328.  
  329. #endif /* _AMITCP */
  330.     return(-1);
  331. }
  332.  
  333. /*****************************************************************************/
  334. void
  335. cleanup_socklib(void)
  336. {
  337. #ifdef _AMITCP
  338.     CloseLibrary(SocketBase);
  339. #else
  340.     cleanup_sockets();
  341.     CloseLibrary(SockBase);
  342. #endif /* _AMITCP */
  343. }
  344.  
  345. /*****************************************************************************/
  346. /* EOF socklink.c */
  347.